define(["moment"], function (moment) {
    return [ "$scope", "$filter", "$stateParams", "config", "MMWService", "$mdDialog", "$timeout", "$css", "$compile",
        function ( $scope, $filter, $stateParams, config, $MMWService, $mdDialog, $timeout, $css, $compile) {
            $scope.init = async () => {
                // 1	进入S1界面，自动跳转进入S2界面
                // 打开生产逆向追溯界面时，无论是否首次进入该界面，都会跳进S2界面。
                $scope.main_page_url = "module/moduleQT/program/QT07/QT07_Query_Page.html";
                $scope.query_event = QueryPageSettingEvent();
                $scope.main_event = MainPageEvent();
                $scope.expand_event = extendEvent();
                $scope.query_setting = [];
                $scope.targetSheet = '';
                $scope.sheetData = [];
            }
            let lotNo = '';
            let extendData = {
                header: [],
                row: []
            }
            let DTList = [];

            $scope.sheet = {};
            $scope.fromMainEvent = false;
            $scope.condition = [];
            $scope.columnList = [];

            $scope.queryMap = new Map();
            $scope.queryCondList = [
                {name:$filter('translate')('common.report.condition.equal'), code:'0'},
                {name:$filter('translate')('common.report.condition.nequal'), code:'1'},
                {name:$filter('translate')('common.report.condition.contain'), code:'2'},
                {name:$filter('translate')('common.report.condition.ncontain'), code:'3'},
                {name:$filter('translate')('common.report.condition.exceed-equal'), code:'4'},
                {name:$filter('translate')('common.report.condition.less-equal'), code:'5'},
                {name:$filter('translate')('common.report.condition.exceed'), code:'6'},
                {name:$filter('translate')('common.report.condition.less'), code:'7'}
            ]

            $scope.getPages = (list, PageConfig) => {
                if (list) {
                    if (PageConfig) {
                        PageConfig.total_page = Math.ceil(list.length / PageConfig.page_count) || 1; //最大頁數 (陣列長度/每頁比數)
                        if (PageConfig.page >= PageConfig.total_page) {
                            PageConfig.page = 0;
                        }
                        var index = PageConfig.page * PageConfig.page_count;
                        return list.slice(index, index + PageConfig.page_count); //回傳該頁數的內容
                    } else {
                        return list;
                    }
                } else {
                    return list;
                }
            };

            const changeMainPage = (url) => {
                $scope.main_page_url = url;
            };

            // 回傳兩個陣列交集部分
            // 20220817 modify by Alan for#113984 : 只比對columnList裡的欄位
            const getIntersectionArray = (arr1, arr2, columnList) => {
                return arr1.filter((value) => arr2.findIndex(val => {
                    const obj1 = {};
                    const obj2 = {};
                    columnList.forEach(column => obj1[column.RESULTFIELD] = val[column.RESULTFIELD]);
                    columnList.forEach(column => obj2[column.RESULTFIELD] = value[column.RESULTFIELD]);
                    return JSON.stringify(obj1) === JSON.stringify(obj2);
                }) != -1);
            }

            // 回傳多個陣列交集部分
            // 20220816 modify by Alan for#113984 : 如果只有一個dataTable就回傳他
            const getIntersectionArrayGroup = (arrayGroup, columnList) => {
                let interArray = [];
                if(arrayGroup.length >= 2) {
                     interArray = getIntersectionArray(arrayGroup.shift(), arrayGroup.shift(), columnList);
                    if(arrayGroup.length >= 1) {
                        interArray = getIntersectionArrayGroup([interArray, ...arrayGroup], columnList);
                    } else {
                        return interArray;
                    }
                } else if(arrayGroup.length === 1){
                    return arrayGroup[0];
                } else {
                    return [];
                }
                return interArray;
            }

            // 回傳指定欄位不重複的陣列
            const getUniqueArray = (array, columnList) => {
                const stringifyArray = array.map(val => {
                    let obj = {};
                    columnList.forEach(column => obj[column.RESULTFIELD] = val[column.RESULTFIELD]);
                    return JSON.stringify(obj);
                });
                const uniqueStringifyArr = [...new Set(stringifyArray)];
                const resultArr = uniqueStringifyArr.map(val => JSON.parse(val));
                return resultArr;
            }

            const service_QTR_Step1 = (content) => {
                return new Promise(async (resolve, reject) => {
                    let result;
                    $MMWService.sendToServer({
                        uri: "ServicesSTD.Module_LEAN.QTR_Step1",
                        content: content,
                        success: (data) => (result = resolve(data)),
                    });

                    return result;
                });
            };

            const service_QTR_Step2 = (content) => {
                return new Promise(async (resolve, reject) => {
                    let result;
                    $MMWService.sendToServer({
                        uri: "ServicesSTD.Module_LEAN.QTR_Step2",
                        content: content,
                        success: (data) => (result = resolve(data)),
                    });

                    return result;
                });
            };

            const getTraceList = async () => {
                const content = {
                    Name: "GetTraceList",
                };
                const traceList = await service_QTR_Step1(content)
                    .then((resp) => resp.TraceList)
                    .catch((err) => $scope.$root.showAlert(err));
                return traceList;
            };

            const getCondList = async (traceNO) => {
                const content = { Name: "GetCondList", TRACENO: traceNO };
                const condList = await service_QTR_Step1(content)
                    .then((resp) => resp.CondList)
                    .catch((err) => $scope.$root.showAlert(err));
                return condList;
            };

            const getTraceData = (condList) => {
                const content = { Name: "GetTraceData", CondList: condList };
                return service_QTR_Step1(content);
            };

            const getPositiveTraceList = async () => {
                const content = { Name: "GetPositiveTraceList"};
                const traceList = await service_QTR_Step2(content)
                    .then((resp) => resp.TraceList)
                    .catch((err) => $scope.$root.showAlert(err));
                return traceList;
            };

            const getCondListAndOrderbyColumn = (traceNo) => {
                const content = {
                    Name: "GetCondListAndOrderbyColumn",
                    TRACENO: traceNo,
                };
                return service_QTR_Step2(content);
            };

            const excelDownload = (option) => {
                const content = {
                    Name: "ExcelDownload",
                    Condition: option.condition,
                    result: option.result,
                    extend:option.extend,
                };
                return service_QTR_Step2(content);
            };

            const getExtraTrace = (option) => {
                const content = {
                    Name: "GetExtraTrace",
                    TRACENO: option.traceNo,
                    CondList: option.condList,
                    orderby: option.orderBy,
                    count: option.count,
                    type: option.type,
                    // F → 向前，B → 向後，M → 前後
                    lotno: option.lotNo
                };
                return service_QTR_Step2(content);
            };

            const exportExcel = async (option) => {
                if (window.nodeRequire) {
                    // 20240321 modify by Alan for#159805 : electron升級後，兼容新舊版本
                    const { remote } = window.nodeRequire('electron');
                    if (remote) {
                        remote.dialog.showOpenDialog({
                            properties: ['openDirectory']
                        }, async (fileList) => {
                            if (fileList && fileList.length > 0) {
                                const resp = await excelDownload(option);
                                if (resp.ExcelFile) {
                                    var file_data = Buffer.from(resp.ExcelFile, "base64");
                                    var file_name = `${fileList[0]}\\REVERSE_TRACE_DATA_${moment().format("YYYYMMDDHHmmss")}.xls`;
                                    window
                                        .nodeRequire("fs")
                                        .writeFile(file_name, file_data, function (error) {
                                            if (error) {
                                                $scope.$root.showAlert(
                                                    $filter("translate")(
                                                        "common.msg.cantDownloadFile"
                                                    ) + error
                                                );
                                            } else {
                                                $scope.$root.showConfirm(
                                                    $filter("translate")(
                                                        "common.msg.file_download_complete_and_open"
                                                    ),
                                                    function (dialog) {
                                                        dialog.hide();
                                                        // 20230807 modify by Alan for#130433 : electron升版後，shell.openItem改成shell.openPath
                                                        const { shell } = window.nodeRequire('electron');
                                                        shell.openItem ? shell.openItem(file_name) : shell.openPath(file_name);
                                                    }
                                                );
                                            }
                                        });
                                }
                            }
                        });
                    } else {
                        const remote = window.nodeRequire('@electron/remote');
                        remote.dialog.showOpenDialog({
                            properties: ['openDirectory']
                        }).then(async (result) => {
                            if (result.filePaths && result.filePaths.length > 0) {
                                const resp = await excelDownload(option);
                                if (resp.ExcelFile) {
                                    var file_data = Buffer.from(resp.ExcelFile, "base64");
                                    var file_name = `${ result.filePaths[0] }\\REVERSE_TRACE_DATA_${ moment().format("YYYYMMDDHHmmss") }.xls`;
                                    window
                                        .nodeRequire("fs")
                                        .writeFile(file_name, file_data, function (error) {
                                            if (error) {
                                                $scope.$root.showAlert(
                                                    $filter("translate")(
                                                        "common.msg.cantDownloadFile"
                                                    ) + error
                                                );
                                            } else {
                                                $scope.$root.showConfirm(
                                                    $filter("translate")(
                                                        "common.msg.file_download_complete_and_open"
                                                    ),
                                                    function (dialog) {
                                                        dialog.hide();
                                                        // 20230807 modify by Alan for#130433 : electron升版後，shell.openItem改成shell.openPath
                                                        const { shell } = window.nodeRequire('electron');
                                                        shell.openItem ? shell.openItem(file_name) : shell.openPath(file_name);
                                                    }
                                                );
                                            }
                                        });
                                }
                            }
                        });
                    }
                }
            };

            const QueryPageSettingEvent = () => {
                return {
                    query_label_list: [
                        {
                            l_type: "normal",
                            code: "A.RONO",
                            label: $filter("translate")("QT07.query.RONO"),
                        },
                        {
                            l_type: "normal",
                            code: "A.MONO",
                            label: $filter("translate")("QT07.query.MONO"),
                        },
                        {
                            l_type: "normal",
                            code: "A.LOTNO",
                            label: $filter("translate")("QT07.query.LOTNO"),
                        },
                    ],
                    query_judgment_list: [
                        {
                            code: '0',
                            label: $filter("translate")("QT07.query_judgment.equal"),
                        },
                        {
                            code: "2",
                            label: $filter("translate")("QT07.query_judgment.contain"),
                        },
                    ],
                    queryCondList: [
                        {name:$filter('translate')('common.report.condition.equal'), code:'0'},
                        {name:$filter('translate')('common.report.condition.nequal'), code:'1'},
                        {name:$filter('translate')('common.report.condition.contain'), code:'2'},
                        {name:$filter('translate')('common.report.condition.ncontain'), code:'3'},
                        {name:$filter('translate')('common.report.condition.exceed-equal'), code:'4'},
                        {name:$filter('translate')('common.report.condition.less-equal'), code:'5'},
                        {name:$filter('translate')('common.report.condition.exceed'), code:'6'},
                        {name:$filter('translate')('common.report.condition.less'), code:'7'}
                    ],
                    select_type_item: {},
                    select_txt_vale: '',
                    select_level_item: {},
                    condition: [],
                    query_setting_detail: [],
                    startTime: moment(),
                    endTime: moment(),
                    displayCondition: [],
                    traceList: [],
                    traceMap: new Map(),
                    selectTRACE: {},
                    conditionList: [],
                    condMap: new Map(),
                    selectCond: {},
                    PageConfig: {
                        page: 0,
                        page_count: 25,
                    },
                    async init() {
                        this.queryCondList.forEach((cond) => {
                            $scope.queryMap.set(cond.code, cond.name);
                        })
                        // 1.1	S2界面初始化
                        // 从质量追溯基本资料表中取得当前界面可见的，且为逆向类别的追溯方式，将其追溯名称列在追溯项目类别中下拉选单中。
                        this.traceList = await getTraceList();
                        this.traceList.forEach((item) => {
                            this.traceMap.set(item.TRACENO, item.TRACENAME);
                        })
                        this.selectTRACE = this.traceList[0];
                        this.conditionList = await getCondList(this.selectTRACE.TRACENO);
                        this.conditionList.forEach((item) => {
                            this.condMap.set(item.CONDFIELD, item.CONDNAME);
                        })
                        this.selectCond = this.conditionList[0];
                        this.select_type_item = $filter('filter')(this.queryCondList, { code: this.selectCond.CONDOPERAND })[0];
                        this.select_txt_vale = '';
                    },
                    loadCodeList(item) {
                        if(this.conditionList.length === 0) {
                            return
                        }
                        $scope.showSelect({
                            title: $filter("translate")("common.report.condition_fields"),
                            label: "CONDNAME",
                            code: "ITEMNO",
                            selectCode: item.ITEMNO,
                            list: this.conditionList,
                            confirm: (selectItem, dialog) => {
                                dialog.hide();
                                this.selectCond = selectItem;
                            },
                        });
                    },
                    loadTypeList(item) {
                        $scope.showSelect({
                            title: $filter("translate")("common.condition_title"),
                            label: "name",
                            code: "code",
                            selectCode: item.code,
                            list: this.queryCondList,
                            confirm: (selectItem, dialog) => {
                                this.select_type_item = selectItem;
                                dialog.hide();
                            },
                        });
                    },
                    loadItemTypeList(item) {
                        $scope.showSelect({
                            title: $filter("translate")("common.condition_title"),
                            label: "TRACENAME",
                            code: "code",
                            selectCode: this.selectTRACE,
                            list: this.traceList,
                            confirm: async (item, dialog) => {
                                dialog.hide();
                                // 1.2	S2选择某项具体的追溯项目类别
                                // 在追溯项目类别下拉选单中选择一个具体的追溯方式编号时，下方的追溯字段中会自动带出当前追溯方式对应的查询字段名称，默认显示序号最靠前的一个，右侧的查询条件默认为预设查询条件字段。
                                this.selectTRACE = item;
                                this.conditionList = await getCondList(item.TRACENO);
                                this.selectCond = this.conditionList[0];
                                this.conditionList.forEach((item) => {
                                    this.condMap.set(item.CONDFIELD, item.CONDNAME);
                                })
                            },
                        });
                    },
                    // 20220816 modify by Alan for#113984 : 修正邏輯
                    removeConditionItem(traceNo, value) {
                        const traceIndex = this.condition.findIndex((item) => item.traceno === traceNo);
                        if(traceIndex != -1 && this.condition[traceIndex].QueryCondition.length > 0) {
                            const condIndex = this.condition[traceIndex].QueryCondition.findIndex(((item) => item.value === value));
                            if(condIndex != -1) {
                                this.condition[traceIndex].QueryCondition.splice(condIndex, 1);
                            }
                            if(this.condition[traceIndex].QueryCondition.length === 0) {
                                this.condition.splice(traceIndex, 1);
                            }
                        }
                        this.displayCondition = this.getFlat(this.condition);
                    },
                    confirm() {
                        // 1.7	S2点击按钮
                        // 击后根据筛选条件追溯查询出结果展示在S1界面，关闭S2
                        getTraceData(this.condition).then((resp) => {
                            if(resp.errMsg && resp.errMsg != '') {
                                $scope.$root.showAlert(resp.errMsg);
                            } else {
                                $scope.condition = angular.copy(this.condition);
                                displayCondition = angular.copy(this.displayCondition);
                                DTList = resp.DTList || [];
                                $scope.columnList = resp.columnList || [];
                                changeMainPage("module/moduleQT/program/QT07/QT07_Main.html");
                            }
                        });
                    },
                    addCondition() {
                        // 1.3	S2点击按钮' + '
                        // 当设定好筛选条件后，点击加号按钮，将对应的数据添加进下方的条件成列界面。
                        // 当选择的查询条件类型为时间区间时，插入下方时自动分为>开始时间和<结束时间两行

                        // 20220816 modify by Alan for#113984 : 修正邏輯
                        if (this.selectCond.CONDDATATYPE != 3 && this.selectCond.CONDDATATYPE != 4) {
                            if (this.select_txt_vale.trim() == '') return;
                            var condition_obj = {
                                traceno: this.selectTRACE.TRACENO,
                                tracename: this.selectTRACE.TRACENAME,
                                QueryCondition: [{
                                    ITEMNO: $filter('filter')(this.conditionList, this.selectCond.CONDFIELD)[0].ITEMNO,
                                    column_name: this.selectCond.CONDFIELD,
                                    showname: this.condMap.get(this.selectCond.CONDFIELD),
                                    require: false,
                                    query_mode: this.select_type_item.code,
                                    merge_condition_model: "AND",
                                    value: ''
                                }],
                            };
                            condition_obj.QueryCondition[0].value = condition_obj.QueryCondition[0].query_mode === '2'
                                ? "%" + this.select_txt_vale + "%"
                                : this.select_txt_vale;

                            var has_repet = $filter("filter")(
                                this.condition,
                                condition_obj,
                                true
                            );
                            if (has_repet.length > 0) return;

                            const hasSameTraceNo = $filter("filter")(this.condition, {traceno: condition_obj.traceno}, true);
                            if (hasSameTraceNo.length > 0 ) {
                                hasSameTraceNo[0].QueryCondition.push(condition_obj.QueryCondition[0]);
                            } else {
                                this.condition.push(condition_obj);
                            }
                        } else {
                            var condition_obj = {
                                traceno: this.selectTRACE.TRACENO,
                                tracename: this.selectTRACE.TRACENAME,
                                QueryCondition: [{
                                    ITEMNO: $filter('filter')(this.conditionList, this.selectCond.CONDFIELD)[0].ITEMNO,
                                    column_name: this.selectCond.CONDFIELD,
                                    showname: this.condMap.get(this.selectCond.CONDFIELD),
                                    require: false,
                                    query_mode: '4',
                                    merge_condition_model: "AND",
                                    value: moment(this.startTime).format('YYYY-MM-DD')
                                }],
                                };

                            var endTimeCondition = {
                                ITEMNO: $filter('filter')(this.conditionList, this.selectCond.CONDFIELD)[0].ITEMNO,
                                column_name: this.selectCond.CONDFIELD,
                                showname: this.condMap.get(this.selectCond.CONDFIELD),
                                require: false,
                                query_mode: '5',
                                merge_condition_model: "AND",
                                value: moment(this.endTime).format('YYYY-MM-DD')
                            };
                            condition_obj.QueryCondition.push(endTimeCondition);

                            var has_repet = $filter("filter")(
                                this.condition,
                                condition_obj,
                                true
                            );
                            if (has_repet.length > 0) return;
                            const hasSameTraceNo = $filter("filter")(this.condition, {traceno: condition_obj.traceno}, true);
                            if (hasSameTraceNo.length > 0 ) {
                                hasSameTraceNo[0].QueryCondition.push(condition_obj.QueryCondition[0]);
                                hasSameTraceNo[0].QueryCondition.push(condition_obj.QueryCondition[1]);
                            } else {
                                this.condition.push(condition_obj);
                            }
                        }
                        this.select_txt_vale = '';

                        this.displayCondition = this.getFlat(this.condition);
                    },
                    loadQuery() {
                        // 1.6	S2点击按钮，打开S4界面
                        // 展示当前账号之前保存的筛选条件模板，用户可自由调出，快速使用
                        $mdDialog.serviceDialog(
                            "QT07_LoadQueryService",
                            {},
                            (dialog) => {
                                this.condition = dialog.traceModel;
                                this.displayCondition = this.getFlat(this.condition);
                            }
                        );
                    },
                    saveQuery() {
                        // 1.5	S2点击按钮，跳出S3界面
                        // 将当前的筛选条件保存成模板，以便下次再调用
                        $mdDialog.serviceDialog(
                            "QT07_SaveQueryService",
                            {
                                traceNo: this.selectTRACE.TRACENO,
                                conditionList: this.condition,
                            },
                            () => {
                            }
                        ); 
                    },
                    isSearched(obj) {
                        return Object.keys(obj).length != 0;
                    },
                    close() {
                        // 1.8	S2点击按钮	
                        // 清除S2界面上记录及缓存，关闭S2
                        this.condition = [];
                        this.query_setting_detail = [];
                        this.displayCondition = [];
                        changeMainPage("module/moduleQT/program/QT07/QT07_Main.html");
                    },
                    clear() {
                        this.query_setting_detail = [];
                    },
                    getFlat(condition) {
                        let list = [];
                        condition.forEach((cond) => {
                            cond.QueryCondition.forEach((item) => {
                                let showData = {
                                    traceName: this.traceMap.get(cond.traceno),
                                    condName: this.condMap.get(item.column_name) || item.showname,
                                    queryName: $scope.queryMap.get(item.query_mode),
                                    value: item.value,
                                    traceNo: cond.traceno,
                                    itemNo: item.ITEMNO
                                }
                                list.push(showData);
                            })
                        })

                        return list;
                    }
                };
            };

            var MainPageEvent = function () {
                return {
                    headerTitle:
                        $filter("translate")("QT07.prefix") +
                        "｜" +
                        $filter("translate")("QT07.title"),
                    model_name: '',
                    TDList: [],
                    condition: [],
                    DTList: [],
                    columnList: [],
                    extendData: {
                        columnList: [],
                        data: []
                    },
                    resultPageConfig: {
                        page: 0,
                        page_count: 25,
                    },
                    extendPageConfig: {
                        page: 0,
                        page_count: 25,
                    }
                    ,async init() {
                        this.condition = $scope.condition;
                        this.displayCondition = displayCondition;
                        this.columnList = $scope.columnList;
                        // 20220817 modify by Alan for#113984 : 只比對columnList裡的欄位，比對後清空DTList
                        if(DTList.length != 0) {
                            // 20220816 modify by Alan for#113984 : 取交集
                            this.DTList = getIntersectionArrayGroup(DTList, this.columnList);
                            // 20220817 modify by Alan for#113984 : 去除取交集後重複資料
                            this.DTList = getUniqueArray(this.DTList, this.columnList);
                            DTList = [];
                        }

                        if (this.columnList.length > 0) {
                            updateResult(this.columnList);
                        }
                        if (extendData.columnList && extendData.columnList.length > 0) {
                            this.extendData = extendData;
                            updateExtend(this.extendData.columnList);
                        }
                    },
                    queryName(querymode) {
                        return $scope.queryMap.get(querymode)
                    },
                    queryPage() {
                        // 2.1	S1点击按钮，跳出S2界面
                        	// 在跳出S2界面，界面上显示之前使用的筛选记录。
                        $scope.fromMainEvent = true;
                        changeMainPage("module/moduleQT/program/QT07/QT07_Query_Page.html");
                    },
                    select(item) {
                        item.isSelect = !item.isSelect;
                    },
                    expandQuery(item) {
                        // 2.2	S1点击按钮，跳出S5界面	
                        // S5为拓展追溯功能，主要是在某个结果生产批的基础上检索满足某些条件的前后一定范围内的生产批，只能选择一个生产批进行拓展追溯。
                        // 点击追溯结果后方的按钮，跳出S5界面。
                        
                        // 20220812 modify by Alan for#113984 : 生產批號要用BASELOTNO
                        lotNo = item.BASELOTNO || item.LOTNO;
                        changeMainPage(
                            "module/moduleQT/program/QT07/QT07_Expand_Query_Page.html"
                        );
                    },
                    goToQT06() {
                        // 2.3	S1点击按钮	
                        // 勾选某条或多条结果数据，无论是追溯结果，或者拓展追溯结果，点击该按钮后出现跳转确认，点击确认后，以当前生产批作为条件进入生产正向追溯界面进行追溯。
                        // 转入正向追溯时，不保存查询模板，且仅以生产批作为0层进行追溯。
                        // 20220812 modify by Alan for#113984 : 生產批號要用BASELOTNO
                        const lotNoList = [];
                        this.DTList.forEach(DT => {
                            let lotNo = DT.BASELOTNO || DT.LOTNO;
                            if(DT.isSelect === true && lotNoList.indexOf(lotNo) === -1) {
                                lotNoList.push(lotNo);
                            }
                        })

                        this.extendData.data.forEach(DT => {
                            let lotNo = DT.BASELOTNO || DT.LOTNO;
                            if(DT.isSelect === true && lotNoList.indexOf(lotNo) === -1) {
                                lotNoList.push(lotNo);
                            }
                        })

                        if(lotNoList.length === 0) {
                            $scope.$root.showAlert($filter("translate")('QT07.errMsg.select_no_data'));
                            return;
                        }
                        
                        $scope.$root.showConfirm(
                            $filter("translate")("QT07.msg.gotoQT06"),
                            function (dialog) {
                                dialog.hide();
                                $scope.$root.changeProgram('QT06', { data: { lotNoList: lotNoList } });
                            }
                        );
                    },
                    async download() {
                        const option = {
                            condition: this.condition,
                            result: {
                                DTList: [this.DTList],
                                columnList: this.columnList
                            },
                            extend: {
                                Data: this.extendData.data,
                                columnList: this.extendData.columnList
                            }
                        }
                        await exportExcel(option);
                    },
                };
            };

            const extendEvent = () => {
                return {
                    lotNo: '',
                    traceList: [],
                    selectTrace: {
                        TRACENAME: '',
                        TRACENO: '',
                        code: 0
                    },
                    condition: [],
                    condList: [],
                    selectCond: {},
                    traceDirectionList: [
                        {
                            code: '0',
                            value: 'F',
                            label: $filter("translate")("QT07.traceDirection.forward"),
                        },
                        {
                            code: "1",
                            value: 'B',
                            label: $filter("translate")("QT07.traceDirection.backward"),
                        },
                        {
                            code: "2",
                            value: 'M',
                            label: $filter("translate")("QT07.traceDirection.both"),
                        },
                    ],
                    selectQueryCondition: {},
                    selectTraceDirection: {},
                    count: 10,
                    inputValue: '',
                    PageConfig: {
                        page: 0,
                        page_count: 25,
                    },
                    traceMap: new Map(),
                    condMap: new Map(),
                    newCondition: new Set(),
                    async init() {
                        // 2.2.1	S5初始化
                        // 界面上当前生产批字段显示的是从S1带过来的生产批号
                        this.lotNo = lotNo;
                        // 获取追溯基本资料表中，生产逆向追溯、可见的、类型为正向的追溯方式，列在追溯项目类别中。
                        this.traceList = await getPositiveTraceList();
                        this.traceList.forEach((item, index) => {
                            item.code = index
                            this.traceMap.set(item.TRACENO, item.TRACENAME);
                        });
                        this.selectTrace = this.traceList[0];
                        
                        // 20220812 modify by Alan for#113984 : 查無追溯編號時中斷
                        // 20220816 modify by Alan for#113984 : 修正邏輯
                        if(!this.selectTrace && this.selectTrace.TRACENO) {
                            return;
                        }
                        const resp = await getCondListAndOrderbyColumn(this.selectTrace.TRACENO);
                        if(resp.CondList.length > 0) {
                            this.condList = resp.CondList;
                            this.condList = $filter('orderBy')(this.condList, 'ITEMNO');
                            this.condList.forEach((item) => {
                                this.condMap.set(item.CONDFIELD, item.CONDNAME);
                            })
                            $timeout(() => this.selectCond = this.condList[0]);
                        }
                        if(resp.columnList.length > 0) {
                            this.columnList = resp.columnList;
                            this.columnList.forEach((item, index) => item.code = index);
                            this.columnList = $filter('orderBy')(this.columnList, 'code');
                            $timeout(() => this.selectExtendSort = this.columnList[0]);
                        }

                        this.selectQueryCondition = $scope.queryCondList[0];
                        this.selectTraceDirection = this.traceDirectionList[0];
                    },
                    loadTraceTypeList(item) {
                        $scope.showSelect({
                            title: $filter("translate")("common.condition_title"),
                            label: "TRACENAME",
                            code: "code",
                            selectCode: item.code,
                            list: this.traceList,
                            confirm: async (item, dialog) => {
                                dialog.hide();
                                // 2.2.2	S5追溯项目类别选择其中一个追溯方式
                                // 拓展追溯条件类取值方式同1.2 拓展排序条件取值为当前追溯方式的结果字段，用以向前、向后、以及前后追溯。
                                // 此处的追溯项目类别中的追溯方式只能选择一种，如已设定了一种，再更改为其他类型时，点击向前、向后、前后按钮将清空当前已选择的类型，更换成新选择的类型。
                                if(this.selectTrace.TRACENO != item.TRACENO) {
                                    this.selectTrace = item;
                                    const resp = await getCondListAndOrderbyColumn(item.TRACENO);
                                    if(resp.CondList.length > 0) {
                                        this.condList = resp.CondList;
                                        this.condList = $filter('orderBy')(this.condList, 'ITEMNO');
                                        this.selectCond = this.condList[0];
                                    }
                                    if(resp.columnList.length > 0) {
                                        this.columnList = resp.columnList;
                                        this.columnList.forEach((item, index) => item.code = index);
                                        this.columnList = $filter('orderBy')(this.columnList, 'code');
                                        this.selectExtendSort = this.columnList[0];
                                    }
                                    $timeout(() => {
                                        this.cancel();
                                    })
                                }
                            },
                        });
                    },
                    loadCodeList(item) {
                        $scope.showSelect({
                            title: $filter("translate")("common.condition_title"),
                            label: "CONDNAME",
                            code: "ITEMNO",
                            selectCode: item.ITEMNO,
                            list: this.condList,
                            confirm: async (item, dialog) => {
                                dialog.hide();
                                this.selectCond = item;
                            },
                        });
                    },
                    loadQueryConditionList(item) {
                        $scope.showSelect({
                            title: $filter("translate")("common.condition_title"),
                            label: "name",
                            code: "code",
                            selectCode: item.code,
                            list: $scope.queryCondList,
                            confirm: (item, dialog) => {
                                this.selectQueryCondition = item;
                                dialog.hide();
                            },
                        });
                    },
                    loadExtendSortList(item) {
                        $scope.showSelect({
                            title: $filter("translate")("common.condition_title"),
                            label: "RESULTNAME",
                            code: "code",
                            selectCode: item.code,
                            list: this.columnList,
                            confirm: (item, dialog) => {
                                dialog.hide();
                                this.selectExtendSort = item;
                            },
                        });
                    },
                    loadTraceDirectionList(item) {
                        $scope.showSelect({
                            title: $filter("translate")("common.condition_title"),
                            label: "label",
                            code: "code",
                            selectCode: item.code,
                            list: this.traceDirectionList,
                            confirm: async (item, dialog) => {
                                dialog.hide();
                                this.selectTraceDirection = item;
                                // 2.2.2	S5追溯项目类别选择其中一个追溯方式
                                // 拓展追溯条件类取值方式同1.2 拓展排序条件取值为当前追溯方式的结果字段，用以向前、向后、以及前后追溯。
                                // 此处的追溯项目类别中的追溯方式只能选择一种，如已设定了一种，再更改为其他类型时，点击向前、向后、前后按钮将清空当前已选择的类型，更换成新选择的类型。
                                
                            },
                        });
                    },
                    addCondition() {
                        if (this.selectCond.CONDDATATYPE != 3 && this.selectCond.CONDDATATYPE != 4) {
                            if (this.inputValue.trim() == '') return;
                            var condition_obj = {
                                traceno: this.selectTrace.TRACENO,
                                QueryCondition: [{
                                    ITEMNO: $filter('filter')(this.condList, this.selectCond.CONDFIELD)[0].ITEMNO,
                                    column_name: this.selectCond.CONDFIELD,
                                    column_display: this.selectCond.CONDNAME,
                                    require: false,
                                    query_mode: this.selectQueryCondition.code,
                                    merge_condition_model: "AND",
                                    value: ''
                                }],
                                display: {
                                    traceName: this.selectTrace.TRACENAME
                                }
                            };
                            condition_obj.QueryCondition[0].value = condition_obj.QueryCondition[0].query_mode === '2'
                                ? "%" + this.inputValue + "%"
                                : this.inputValue;
                                
                            const hasSameTraceNo = $filter("filter")(this.condition, {traceno: condition_obj.traceno}, true);
                            if (hasSameTraceNo.length > 0 ) {
                                const hasSameCondition = $filter("filter")(hasSameTraceNo[0].QueryCondition, condition_obj.QueryCondition[0], true);
                                if(hasSameCondition.length > 0){
                                    return;
                                }else{
                                    hasSameTraceNo[0].QueryCondition.push(condition_obj.QueryCondition[0]);
                                }
                            } else {
                                this.condition.push(condition_obj);
                            }
                            
                        } else {
                            var condition_obj = {
                                traceno: this.selectTrace.TRACENO,
                                QueryCondition: [{
                                    ITEMNO: $filter('filter')(this.condList, this.selectCond.CONDFIELD)[0].ITEMNO,
                                    column_name: this.selectCond.CONDFIELD,
                                    column_display: this.selectCond.CONDNAME,
                                    require: false,
                                    query_mode: '4',
                                    merge_condition_model: "AND",
                                    value: moment(this.startTime).format('YYYY-MM-DD')
                                }],
                                display: {
                                    traceName: this.selectTrace.TRACENAME
                                }
                            };

                            var endTimeCondition = {
                                ITEMNO: $filter('filter')(this.condList, this.selectCond.CONDFIELD)[0].ITEMNO,
                                column_name: this.selectCond.CONDFIELD,
                                column_display: this.selectCond.CONDNAME,
                                require: false,
                                query_mode: '5',
                                merge_condition_model: "AND",
                                value: moment(this.endTime).format('YYYY-MM-DD')
                            };
                            condition_obj.QueryCondition.push(endTimeCondition);

                            var has_repet = $filter("filter")(
                                this.condition,
                                condition_obj,
                                true
                            );
                            if (has_repet.length > 0) return;

                            this.condition.push(condition_obj);
                        }
                        this.inputValue = '';

                        this.displayCondition = this.getFlat(this.condition);
                    },
                    getFlat(condition) {
                        let list = [];
                        condition.forEach((cond) => {
                            cond.QueryCondition.forEach((item) => {
                                let showData = {
                                    traceName: this.traceMap.get(cond.traceno),
                                    condName: item.column_display,
                                    queryName: $scope.queryMap.get(item.query_mode),
                                    value: item.value,
                                    traceNo: cond.traceno,
                                    itemNo: item.ITEMNO
                                }
                                list.push(showData);
                            })
                        })
                        return list;
                    },
                    changeCount(value) {
                        // count不可小於1
                        if((this.count + value) > 0) {
                            this.count += value
                        }
                    },
                    async confirm() {
                        const option = {
                            traceNo: this.selectTrace.TRACENO,
                            condList: [],
                            orderBy: this.selectExtendSort.RESULTFIELD,
                            count: this.count,
                            type: this.selectTraceDirection.value,
                            lotNo: this.lotNo
                        }
                        this.condition.forEach(item => {
                            item.QueryCondition.forEach(query => {
                                option.condList.push(query);
                            })
                        })
                        const resp = await getExtraTrace(option);
                        if(resp.errMsg) {
                            const key = 'QT07.errMsg.' + resp.errMsg;
                            $scope.$root.showAlert($filter("translate")(key));
                            return;
                        }
                        if(resp.Data && resp.columnList) {
                            extendData.columnList = resp.columnList;
                            extendData.data = resp.Data;
                            
                            this.close();
                        } 
                    },
                    close() {
                        this.cancel();
                        changeMainPage(
                            "module/moduleQT/program/QT07/QT07_Main.html"
                        );
                    },
                    cancel() {
                        this.displayCondition = [];
                        this.condition = [];
                    }
                };
            };  

            // 動態載入表單
            function updateResult(item) {
                let list = generateResultHeader(item);
                if ($('.result-list').length != 0) {
                    $('.result-list').replaceWith(list);
                }
                $compile(list)($scope);
            }

            function generateResultHeader(item) {
                let rows = generateResultRow(item);
                let start = `<div class="kmi-list column-selector">
                                <div class="kmi-list__header">
                                    <div class="kmi-list__column" style="flex: 0 0 50px;"></div>
                                    <div class="kmi-list__column" style="flex: 0 0 50px;"></div>`;
                let end = `     </div>
                                <div class="kmi-list__row-content">
                                    ${rows}
                                </div>
                            </div>`;
                let columns = ''
                item.forEach(field => 
                    columns += `<div class="kmi-list__column" style="flex: 0 0 120px;" ng-bind="'${ field.SHOWNAME }'"></div>`);
                let list = $(start + columns + end);

                return list
            }

            function generateResultRow(item) {
                var row = '';
                var columns = ``
                var start = `<div class="kmi-list__row" ng-class="{'is-select': data.isSelect}" ng-repeat="data in getPages(main_event.DTList, main_event.resultPageConfig) track by $index">
                                <div class="kmi-list__column column-border">
                                    <div class="check-box">
                                        <img ng-src="{{ data.isSelect ? 'image/smes_v340/checkbox_true.png' : 'image/smes_v340/checkbox_false.png' }}">
                                    </div>
                                </div>
                                <div class="kmi-list__column column-border">
                                    <img src='image/smes_v340/menu/W_Com_Report_Insert_nor_32.png' ng-click="main_event.expandQuery(data)"></img>
                                </div>`;
                var end =   `   <div class="kmi-can-click" ng-click="main_event.select(data)"></div>
                            </div>`;
                item.forEach(field => 
                    columns += `<div class="kmi-list__column column-border" style="flex: 0 0 120px;" ng-bind="data.${ field.RESULTFIELD }"></div>`);
                row = start + columns + end;

                return row;
            }

            // 動態載入表單
            function updateExtend(item) {
                let list = generateExtendHeader(item);
                if ($('.extend-list').length != 0) {
                    $('.extend-list').replaceWith(list);
                }
                $compile(list)($scope);
            }

            function generateExtendHeader(item) {
                let rows = generateExtendRow(item);
                let start = `<div class="kmi-list column-selector">
                                <div class="kmi-list__header">
                                    <div class="kmi-list__column" style="flex: 0 0 50px;"></div>`;
                let end = `     </div>
                                <div class="kmi-list__row-content">
                                    ${rows}
                                </div>
                            </div>`;
                let columns = ''
                item.forEach(field => 
                    columns += `<div class="kmi-list__column" style="flex: 0 0 120px;" ng-bind="'${ field.RESULTNAME }'"></div>`);
                let list = $(start + columns + end);

                return list
            }

            function generateExtendRow(item) {
                var row = '';
                var columns = ``
                var start = `<div class="kmi-list__row" ng-class="{'is-select': data.isSelect}" ng-repeat="data in getPages(main_event.extendData.data, main_event.extendPageConfig) track by $index">
                                <div class="kmi-list__column column-border">
                                    <div class="check-box">
                                        <img ng-src="{{ data.isSelect ? 'image/smes_v340/checkbox_true.png' : 'image/smes_v340/checkbox_false.png' }}">
                                    </div>
                                </div>`;
                var end =   `   <div class="kmi-can-click" ng-click="main_event.select(data)"></div>
                            </div>`;
                item.forEach(field => 
                    columns += `<div class="kmi-list__column column-border" style="flex: 0 0 120px;" ng-bind="data.${ field.RESULTFIELD }"></div>`);
                row = start + columns + end;

                return row;
            }
        },
    ];
});
